#include <iostream>

#include "CXX/Objects.hxx"
#include "CXX/Extensions.hxx"
#include "lock.h"

class Module : public Py::ExtensionModule<Module>
{
public:
    Module() : Py::ExtensionModule<Module>("Module")
    {
        add_keyword_method("func", &Module::func, "documentation for func()");

        initialize("This module is the MyModule module."); // register with Python

        Py::Dict d(moduleDictionary());
        d["var"] = Py::String("var value");
    }


    Py::Object func(const Py::Tuple& args, const Py::Dict& kwds)
    {
        std::cout << "func Called with " << args.length() << " normal arguments." << std::endl;
        Py::List names(kwds.keys());
        std::cout << "and with " << names.length() << " keyword arguments:" << std::endl;
        for (Py::List::size_type i = 0; i < names.length(); i++)
        {
            Py::String name(names[i]);
            std::cout << "    " << name << std::endl;
        }

#ifdef PYCXX_DEBUG
        if (args.length() > 0)
        {
            Py::Object x(args[0]);
            PyObject* x_p = x.ptr();
            std::cout << "func( self=0x" << std::hex << reinterpret_cast<unsigned long>(x_p) << std::dec << " )" << std::endl;
            Py::PythonClassInstance* instance_wrapper = reinterpret_cast<Py::PythonClassInstance*>(x_p);
            new_style_class* instance = static_cast<new_style_class*>(instance_wrapper->m_pycxx_object);
            std::cout << "    self->cxx_object=0x" << std::hex << reinterpret_cast<unsigned long>(instance) << std::dec << std::endl;
        }

        bpt();
#endif

        return Py::None();
    }

    virtual ~Module() {}

private:
};

PyObject* initModule()
{
    //PyGILStateLocker lock;
    Module* module = new Module;
    return module->module().ptr();
}

#if defined( _WIN32 )
#define DLL_API _declspec(dllexport)
#else
#define DLL_API _declspec(dllimport)
#endif

extern "C" DLL_API PyObject * PyInit_Module()
{
    std::cout << "sizeof(int) " << sizeof(int) << std::endl;
    std::cout << "sizeof(long) " << sizeof(long) << std::endl;
    std::cout << "sizeof(Py_hash_t) " << sizeof(Py_hash_t) << std::endl;

    std::cout << "has invoke" << std::endl;

    return initModule();
}

//#define PyMOD_INIT_FUNC(name) PyMODINIT_FUNC PyInit_##name(void)
//
//PyMOD_INIT_FUNC(pyd)
//{
//    return initModule();
//}